import os
import re
import sys


from System.Diagnostics import Process



def Main():

    asmFileName, vcsDirectory = HandleArguments()

    revNr = QueryRevNr(vcsDirectory)

    underTeamCity, buildNr = DetectTeamCityAndBuildNr()

    asvFileName = InsertVerInfix(asmFileName)

    PatchAssemblyInfo(asmFileName, asvFileName, revNr, buildNr, lambda x: PrintVersionNr(underTeamCity,x))

    exit(0)




def HandleArguments():

    if len(sys.argv) != 3:                                           
        print "Usage: "                                              
        print "%s assembly-info svn-dir" % sys.argv[0]               
        exit(-1)                                                     
                                                                     
    ### Check arguments                                              
                                                                     
    asmFileName = sys.argv[1]
    vcsDirectory = sys.argv[2]

    if not os.access(asmFileName, os.F_OK):                          
        print "Assembly file: \"%s\" doesn't exist." % asmFileName   
        exit(-2)                                                     
                                                                     
    if not os.access(asmFileName, os.R_OK):                          
        print "Could not access assembly file: \"%s\"" % asmFileName 
        exit(-2)                                                     
                                                                     
    #if not os.access(vcsDirectory, os.F_OK):                        
    #    print "The \"%s\" seems not a directory." % vcsDirectory    
    #    exit(-3)                                                    

    return (asmFileName, vcsDirectory)



def QueryRevNr(vcsDirectory):

    ### Query the revision number                                       
                                                                        
    proc = Process()                                                    
                                                                        
    proc.StartInfo.UseShellExecute = False                              
    proc.StartInfo.RedirectStandardInput = False                        
    proc.StartInfo.RedirectStandardOutput = True                        
    proc.StartInfo.RedirectStandardError = False                        
    proc.StartInfo.FileName = "svn.exe"                                 
    proc.StartInfo.Arguments = "info " + vcsDirectory                   
                                                                        
    proc.Start()                                                        
    proc.WaitForExit()                                                  
                                                                        
    vcsOut = proc.StandardOutput.ReadToEnd()                            
                                                                        
    revLinePattern = re.compile(r"^Last.*Rev:\s*(\d+)\s*$", re.I|re.M)  
    revMatched = revLinePattern.search(vcsOut)                          
    if revMatched:                                                      
        revNr = revMatched.group(1)                                     
    else:                                                               
        revNr = 0                                                       

    return revNr



def DetectTeamCityAndBuildNr():

    underTeamCity = os.environ.get('TEAMCITY_VERSION',"") != ""

    if underTeamCity:
        buildNr = os.environ.get('BUILD_NUMBER','0')
    else:
        buildNr = '0'

    return (underTeamCity, buildNr)



def InsertVerInfix(asmFileName):

    asvFileName = re.compile(r"^(.+)\.cs$",re.I).sub(r"\1Ver.cs",asmFileName,1)
    return asvFileName


def PrintVersionNr(underTeamCity, fullVersion):

    print fullVersion                                                                    
    if underTeamCity:                                                                    
        print "##teamcity[buildNumber '%s']" % fullVersion                               


def PatchAssemblyInfo(asmFileName, asvFileName, revNr, buildNr, handler):

    ### Make the assembly info                                                                      
                                                                                                    
    version_line_pattern = re.compile(r"\[assembly:.*(Assembly.*Version)\D*(\d+.\d+.)(\d+).(\d+).*")
                                                                                                    
    etalon_f = open(asmFileName, "r", 1)                                                            
    patched_f = open(asvFileName, "w")                                                              
    for line in etalon_f:                                                                           
        matched = version_line_pattern.match(line)                                                  
        if matched:                                                                                 
           fullVersion = matched.group(2) + revNr + "." + buildNr
           if matched.group(1) == "AssemblyVersion":
               handler(fullVersion)
           patched_line = line[:matched.start(2)] + fullVersion + line[matched.end(4):]             
           patched_f.write(patched_line)                                                            
        else:                                                                                       
           patched_f.write(line)                                                                    
    patched_f.close()                                                                               
    etalon_f.close()                                                                                


Main()



